/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.hazardsource.service.impl;

import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.hazardsource.bean.DictIndication;
import com.koron.hazardsource.bean.DictIndicationItem;
import com.koron.hazardsource.domain.IndicationItems;
import com.koron.hazardsource.domain.IndicationType;
import com.koron.hazardsource.mapper.IndicationItemsMapper;
import com.koron.hazardsource.mapper.IndicationTypeMapper;
import com.koron.hazardsource.service.api.IndicationTypeService;
import com.koron.hazardsource.util.BusinessCode;
import com.koron.system.domain.DictData;
import com.koron.system.domain.DictType;
import com.koron.system.service.api.DictTypeService;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class IndicationTypeServiceImpl implements IndicationTypeService {

    private final static  Logger logger = LoggerFactory.getLogger(IndicationTypeServiceImpl.class);

    @Autowired
    private DictTypeService dictTypeService;

    @Override
    public MessageBean<Integer> save(IndicationType bean) {
        MessageBean<Integer> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(bean.getName()) || StringUtils.isEmpty(bean.getTypeKey()) || StringUtils.isEmpty(bean.getModule())) {
                msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
                return msg;
            }
            Integer value = 0;
            if (StringUtils.isEmpty(bean.getId())) {
                //新增
                Integer count = factory.getMapper(IndicationTypeMapper.class).isExistByNameOrKey(bean.getName(), bean.getTypeKey());
                if (count > 0) {
                    msg.setCode(BusinessCode.MESSAGE_CODE_INDICATIONTYPE_DOUBLE_NAME);
                    msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_INDICATIONTYPE_DOUBLE_NAME);
                    return msg;
                }
                bean.setId(DefaultIdGenerator.getInstance().generateLongId());
                bean.setAddTime(bean.getUpdateTime());
                bean.setAddUser(bean.getUpdateUser());
                value = factory.getMapper(IndicationTypeMapper.class).insert(bean);
            } else {
                //修改
                Integer count = factory.getMapper(IndicationTypeMapper.class).isExistByNameOrKeyExcludeSelf(bean.getId(), bean.getName(), bean.getTypeKey());
                if (count > 0) {
                    msg.setCode(BusinessCode.MESSAGE_CODE_INDICATIONTYPE_DOUBLE_NAME);
                    msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_INDICATIONTYPE_DOUBLE_NAME);
                    return msg;
                }
                value = factory.getMapper(IndicationTypeMapper.class).update(bean);
            }
            if (value > 0) {
                msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
                msg.setDescription("保存成功");
                msg.setData(value);
                return msg;
            } else {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("保存失败");
                msg.setData(value);
                return msg;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
    }

    @Override
    public MessageBean<Integer> batchDelete(List<String> idList) {
        MessageBean<Integer> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            if (null == idList || idList.size() <= 0) {
                msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
                return msg;
            }
            List<String> delIdList = new ArrayList<>();
            for (String id : idList) {
                IndicationType type = queryOne(id).getData();
                if (null != type) {
                    List<IndicationItems> itemsList = factory.getMapper(IndicationItemsMapper.class).queryAll(type.getName(),
                            null, null, null);
                    if (itemsList == null || itemsList.size() <= 0)
                        delIdList.add(id);
                }
            }
            if (delIdList == null || delIdList.size() <= 0) {
                msg.setCode(BusinessCode.MESSAGE_CODE_INDICATIONTYPE_HAVE_ITEMS);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_INDICATIONTYPE_HAVE_ITEMS);
                return msg;
            }
            Integer value = factory.getMapper(IndicationTypeMapper.class).batchDetele(delIdList);
            if (value > 0) {
                msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
                msg.setDescription("删除成功");
                msg.setData(value);
                return msg;
            } else {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("删除失败");
                msg.setData(value);
                return msg;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
    }

    @Override
    public MessageBean<IndicationType> queryOne(String id) {
        MessageBean<IndicationType> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(id)) {
                msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
                return msg;
            }
            IndicationType type = factory.getMapper(IndicationTypeMapper.class).queryOne(id);
            msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
            msg.setDescription("获取指标项详情成功");
            msg.setData(type);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
    }

    @Override
    public MessageBean<DataBean<IndicationType>> query(Integer start, Integer rows) {
        MessageBean<DataBean<IndicationType>> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            List<IndicationType> typeList = factory.getMapper(IndicationTypeMapper.class).queryAll(start, rows);
            Integer totalNumber = factory.getMapper(IndicationTypeMapper.class).countAll();
            rows = rows == null || rows <= 0 ? 1 : rows;
            Integer totalPage = totalNumber > rows ? (totalNumber % rows == 0 ? totalNumber / rows : totalNumber / rows + 1) : 1;
            DataBean<IndicationType> dataBean = new DataBean<>();
            dataBean.setList(typeList);
            dataBean.setTotalNumber(totalNumber);
            dataBean.setTotalPage(totalPage);
            dataBean.setPageSize(rows == null || rows <= 0 ? 1 : rows);
            msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
            msg.setDescription("获取指标项列表成功");
            msg.setData(dataBean);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
    }

    @Override
    public IndicationType fetchForKey(String typeKey) {
        try (SessionFactory factory = new SessionFactory()) {
            IndicationType type = factory.getMapper(IndicationTypeMapper.class).queryByKey(typeKey);
            if (Objects.nonNull(type)) {
                List<IndicationItems> indicationItems = factory.getMapper(IndicationItemsMapper.class).queryByKey(typeKey);
                Collections.sort(indicationItems, Comparator.comparing(IndicationItems::getIndicationIndex));
                type.setIndicationItems(indicationItems);
                return type;
            }
        }
        return null;
    }

    @Override
    public List<DictIndication> combineDictIndication() throws Exception {
        List<DictIndication> dictIndicationList = new ArrayList<>();
        try (SessionFactory factory = new SessionFactory()) {
            Integer start = null, rows = null;
            List<IndicationType> typeList = factory.getMapper(IndicationTypeMapper.class).queryAll(start, rows);
            List<IndicationItems> indicationItems = factory.getMapper(IndicationItemsMapper.class).queryAll(null, null, start, rows);
            if (Objects.nonNull(typeList) && !typeList.isEmpty()) {
                for (IndicationType type : typeList) {
                    try {
                        DictIndication dest = new DictIndication();
                        PropertyUtils.copyProperties(dest, type);
                        dest.setKey(type.getTypeKey());
                        List<IndicationItems> collect = indicationItems.stream().filter(item -> item.getTypeKey().equals(type.getTypeKey())).collect(Collectors.toList());
                        if (!collect.isEmpty()) {
                            List<DictIndicationItem> items = collect.stream().map(one -> {
                                DictIndicationItem indicationItem = new DictIndicationItem();
                                try {
                                    PropertyUtils.copyProperties(indicationItem, one);
                                    indicationItem.setLabel(one.getName());
                                    indicationItem.setIndex(one.getIndicationIndex());
                                } catch (Exception ex) {
                                    logger.error(ex.getMessage());
                                }
                                return indicationItem;
                            }).collect(Collectors.toList());
                            dest.setItems(items);
                        } else {
                            dest.setItems(Collections.emptyList());
                        }
                        dictIndicationList.add(dest);
                    } catch (Exception e) {
                        logger.error(e.getMessage(),e);
                    }
                }
            }
        } catch (Exception exception) {
            throw new Exception("");
        }

        MessageBean<List<DictType>> messageBean = dictTypeService.getDictTypesAndDictDatas(null);
        List<DictType> data = messageBean.getData();
        if (Objects.nonNull(data) && !data.isEmpty()) {
            for (DictType dt : data) {
                try {
                    DictIndication dest = new DictIndication();
                    PropertyUtils.copyProperties(dest, dt);
                    dest.setKey(dt.getDictKey());
                    List<DictData> dictDataList = dt.getDataList();
                    if (Objects.nonNull(dictDataList) && !dictDataList.isEmpty()) {
                        List<DictIndicationItem> collect = dictDataList.stream().map(one -> {
                            DictIndicationItem indicationItem = new DictIndicationItem();
                            try {
                                PropertyUtils.copyProperties(indicationItem, one);
                                indicationItem.setLabel(one.getDictLabel());
                                indicationItem.setIndex(one.getDictIndex());
                                indicationItem.setValue(one.getDictValue());
                                if (StringUtils.isNotEmpty(indicationItem.getRemark())) {
                                    indicationItem.setRemark(indicationItem.getRemark().replace("\\n", "\n").replace("\\r", "\r"));
                                }
                            } catch (Exception ex) {
                                logger.error(ex.getMessage());
                            }
                            return indicationItem;
                        }).collect(Collectors.toList());
                        dest.setItems(collect);
                    } else {
                        dest.setItems(Collections.emptyList());
                    }
                    dictIndicationList.add(dest);
                } catch (Exception e) {
                    logger.error(e.getMessage(),e);
                }
            }
        }
        return dictIndicationList;
    }


}
